import { OrderInfo } from '@inbiz/hooks';
import { SorterResult } from 'antd/lib/table/interface';
import { ConditionsType, RecordType } from './interfaces';
import {
  arrIsEmpty,
  ConnectorEnum,
  OperatorEnum,
} from './shared';
import moment from 'moment';

/**
 * 获取模型
 * @param queryFields 查询器配置字段
 */
const getModels = (queryFields?: any[]) => {
  if (arrIsEmpty(queryFields) || !queryFields) {
    return {};
  }
  return queryFields.reduce((modal, next) => {
    modal[next.value] = next;
    return modal;
  }, {});
};

/**
 * 获取模型名字
 * @param fieldName 字段名
 * @param models 模型
 */
const getModelName = (fieldName: string, models: any): string[] => {
  if (!models[fieldName]) {
    return ['', fieldName];
  }
  return models[fieldName].origin_FieldName.split('$');
};

/**
 * 格式化排序参数
 * @param orders 排序参数
 * @param sorter 表格排序字段
 * @param models 模型
 */
const formatOrders = (
  orders: OrderInfo[],
  sorter: SorterResult<RecordType>,
  models: any,
): OrderInfo[] => {
  const oldOrder = orders.find((item) => item.fieldName === sorter.field);
  if (!oldOrder) {
    if (sorter.column) {
      const [modelName, fieldName] = getModelName(sorter.field as string, models);
      const order: OrderInfo = {
        modelName,
        fieldName,
        sortType: sorter.order === 'ascend' ? 'asc' : 'desc',
        order: orders.length,
      };
      return [...orders, order];
    }
  } else {
    const filter = orders.filter((item) => item.fieldName !== sorter.field);
    if (sorter.column) {
      const order: OrderInfo = {
        ...oldOrder,
        sortType: sorter.order === 'ascend' ? 'asc' : 'desc',
      };
      return [...filter, order];
    } else {
      return filter;
    }
  }
  return [];
};

/**
 * 格式化查询参数
 * @param field 字段
 * @param condition 查询条件
 * @param queryGroup 查询条件
 */
const formatValue = (
  field: { value: any; type: string },
  condition: {
    connector?: ConnectorEnum;
    field?: string;
    modelName?: any;
    operator: any;
    value?: any;
  },
  queryGroup: { index?: number; connector?: ConnectorEnum; condition: any },
) => {
  const { value, type } = field || {};
  if (value == null) {
    condition.value = value;
    return queryGroup.condition.push(condition);
  }
  switch (type) {
    case 'EformDateRangePicker': {
      const [start, end] = Array.isArray(value) ? value : [];
      if (!start) {
        return;
      }
      condition.operator = OperatorEnum.gte;
      condition.value = moment(start).format('YYYY-MM-DD hh:mm:ss');
      queryGroup.condition.push(condition);
      const endQuery = { ...condition };
      endQuery.operator = OperatorEnum.lte;
      endQuery.value = moment(end).format('YYYY-MM-DD hh:mm:ss');
      return queryGroup.condition.push(endQuery);
    }
    case 'EformDatePicker': {
      condition.value = moment(value).format('YYYY-MM-DD');
      return queryGroup.condition.push(condition);
    }
    case 'EformNumber': {
      condition.operator = OperatorEnum.eq;
      condition.value = value;
      return queryGroup.condition.push(condition);
    }
    case 'EformMemberSelect': {
      if (Array.isArray(value)) {
        condition.connector = value.length > 1 ? ConnectorEnum.or : ConnectorEnum.and;
        condition.value = value.map((item: any) => item.Id).join();
      } else {
        condition.value = value;
      }
      return queryGroup.condition.push(condition);
    }
    case 'EformDynamicList': {
      if (Array.isArray(value)) {
        condition.connector = value.length > 1 ? ConnectorEnum.or : ConnectorEnum.and;
        condition.value = value.join();
      } else {
        condition.value = value;
      }
      return queryGroup.condition.push(condition);
    }
    case 'Cascader': {
      if (Array.isArray(value)) {
        condition.connector = value.length > 1 ? ConnectorEnum.or : ConnectorEnum.and;
        condition.value = value.join();
      } else {
        condition.value = value;
      }
      return queryGroup.condition.push(condition);
    }
    case 'TreeSelect': {
      if (Array.isArray(value)) {
        condition.connector = value.length > 1 ? ConnectorEnum.or : ConnectorEnum.and;
        condition.value = value.join();
      } else {
        condition.value = value;
      }
      return queryGroup.condition.push(condition);
    }
    default: {
      condition.value = value;
      return queryGroup.condition.push(condition);
    }
  }
};

/**
 * 过滤查询条件，剔除查询值不存在和删除字符串前后空格
 * @param conditions 查询条件
 * @returns 过滤后的条件
 */
const filterCondition = (conditions: any) => {
  let cache: any = [];
  if (conditions && conditions.length) {
    conditions.forEach(({ condition, ...other }: any) => {
      let group = { ...other, condition: [] } as any;
      condition.forEach(({ value, field, ...item }: any) => {
        const cacheValue = typeof value === 'string' ? value.trim() : value;
        if (cacheValue != null && cacheValue !== '') {
          let modelName, fieldName;
          if ((field ?? '').indexOf('$') != -1) {
            [modelName, fieldName] = field.split('$');
          } else {
            fieldName = field;
            modelName = '';
          }
          group.condition.push({
            value: cacheValue,
            field: fieldName,
            modelName,
            ...item,
          });
        }
      });
      if (group.condition.length) {
        cache.push(group);
      }
    });
  }
  return cache;
};

/**
 * 组装查询参数
 * @param queryFields 查询器配置字段
 * @param values 查询框表单值
 */
const getQueryGroups = (queryFields: any[], values: { [x: string]: any }): ConditionsType[] => {
  const models = getModels(queryFields);
  const conditions = {
    index: 0,
    connector: ConnectorEnum.and,
    condition: [],
  };
  Object.keys(values).forEach((field) => {
    const [modelName, fieldName] = getModelName(field, models);
    const condition = {
      connector: ConnectorEnum.and,
      field: fieldName,
      modelName,
      operator: OperatorEnum.like,
    };
    formatValue(values[field], condition, conditions);
  });

  return [conditions];
};

const formatters = {
  formatOrders,
  getModels,
  getModelName,
  formatValue,
  getQueryGroups,
  filterCondition,
};

export default formatters;
